/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package listeners;

import data.PredefinedObjects;
import diagram.Graphical;
import diagram.Node;
import diagram.handles.ConnectHandle;
import diagram.handles.TriggerHandle;
import diagram.locations.AbsoluteLocation;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import model.DiagramModel;

/**
 *
 * @author Jelle
 */
public class DropListener implements DropTargetListener {

    private DiagramModel model;
    private PredefinedObjects objects;
    protected JPanel pane;
    protected DropTarget dropTarget;

    public DropListener(JPanel pane, DiagramModel model) {
        this.pane = pane;
        dropTarget = new DropTarget(pane, DnDConstants.ACTION_COPY_OR_MOVE, this, true, null);
        this.model = model;
        objects = new PredefinedObjects();
    }

    // Implementation of the DropTargetListener interface
    public void dragEnter(DropTargetDragEvent dtde) {

        // Get the type of object being transferred and determine
        // whether it is appropriate.
        //checkTransferType(dtde);

        // Accept or reject the drag.
        // acceptOrRejectDrag(dtde);
    }

    public void dragExit(DropTargetEvent dte) {
        System.out.println("DropTarget dragExit");
    }

    public void dragOver(DropTargetDragEvent dtde) {
        // System.out.println("DropTarget dragOver, drop action = ");
        // Accept or reject the drag
        //acceptOrRejectDrag(dtde);
    }

    public void dropActionChanged(DropTargetDragEvent dtde) {
        System.out.println("DropTarget dropActionChanged, drop action = ");

    // Accept or reject the drag
    // acceptOrRejectDrag(dtde);
    }

    public void drop(DropTargetDropEvent dtde) {
        System.out.println("DropTarget drop, drop action = ");
        // Check the drop action
        if ((dtde.getDropAction() & DnDConstants.ACTION_COPY_OR_MOVE) != 0) {
            // Accept the drop and get the transfer data
            dtde.acceptDrop(dtde.getDropAction());
            Transferable transferable = dtde.getTransferable();
            System.out.println(transferable.getClass().getName());
            try {
                for (DataFlavor d : transferable.getTransferDataFlavors()) {
                    ImageIcon b = (ImageIcon) transferable.getTransferData(d);
                    if (b.getDescription().equals("node")) {
                        Node n = new Node();
                        //n = objects.getSimpleNode();
                        n.setUpperLeft(new AbsoluteLocation((int) dtde.getLocation().getX(), (int) dtde.getLocation().getY()));
                        model.addObject(n);
                        System.out.println("new node dragged");
                    } else if (b.getDescription().equals("handle")) {
                        TriggerHandle ht = null;
                        for (Graphical g : model.getObjects("node")) {
                            Node n = (Node) g;
                            int k1 = (int) dtde.getLocation().getX();
                            int k2 = (int) dtde.getLocation().getY();
                            if (n.contains(k1, k2)) {
                                ht = new TriggerHandle(n, 5);
                            } else {
                                ht = new TriggerHandle();
                                ht.setLocation(new AbsoluteLocation((int) dtde.getLocation().getX(), (int) dtde.getLocation().getY()));
                            }
                        }
                        model.addObject(ht);
                        System.out.println("new handle dragged");
                    } else if (b.getDescription().equals("connect")) {
                        for (Graphical g : model.getObjects("node")) {
                            Node n = (Node) g;
                            int k1 = (int) dtde.getLocation().getX();
                            int k2 = (int) dtde.getLocation().getY();
                            if (n.contains(k1, k2)) {
                                ConnectHandle h = new ConnectHandle(n);
                                model.addObject(h);
                                System.out.println("new connecthandle dragged");
                            }
                            System.out.println("NOT new connecthandle dragged (drag on node to attach)");
                        }
                    }
                }
                dtde.dropComplete(true);
            } catch (UnsupportedFlavorException ufe) {
                System.out.println("importData: unsupported data flavor");
                dtde.dropComplete(false);
                dtde.rejectDrop();
            } catch (IOException ioe) {
                System.out.println("importData: I/O exception");
                dtde.dropComplete(false);
                dtde.rejectDrop();
            }
        }
    }
//      try {
//        boolean result = dropComponent(transferable);

//        dtde.dropComplete(result);
//        System.out.println("Drop completed, success: " + result);
//      } catch (Exception e) {
//        System.out.println("Exception while handling drop " + e);
//        dtde.dropComplete(false);
//      }
//    } else {
//      System.out.println("Drop target rejected drop");
//      dtde.rejectDrop();
//    }
//  }

    // Internal methods start here

//  protected boolean acceptOrRejectDrag(DropTargetDragEvent dtde) {
//    int dropAction = dtde.getDropAction();
//    int sourceActions = dtde.getSourceActions();
//    boolean acceptedDrag = false;
//
//
//    // Reject if the object being transferred
//    // or the operations available are not acceptable.
//    if (!acceptableType
//        || (sourceActions & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
//      dtde.rejectDrag();
//    } else if ((dropAction & DnDConstants.ACTION_COPY_OR_MOVE) == 0) {
//      // Not offering copy or move - suggest a copy
//      dtde.acceptDrag(DnDConstants.ACTION_COPY);
//      acceptedDrag = true;
//    } else {
//      // Offering an acceptable operation: accept
//      dtde.acceptDrag(dropAction);
//      acceptedDrag = true;
//    }
//
//    return acceptedDrag;
//  }

//  protected void checkTransferType(DropTargetDragEvent dtde) {
//    // Only accept a flavor that returns a Component
//    acceptableType = false;
//    DataFlavor[] fl = dtde.getCurrentDataFlavors();
//    for (int i = 0; i < fl.length; i++) {
//      Class dataClass = fl[i].getRepresentationClass();
//
//      if (Component.class.isAssignableFrom(dataClass)) {
//        // This flavor returns a Component - accept it.
//        targetFlavor = fl[i];
//        acceptableType = true;
//        break;
//      }
//    }
//
//    System.out.println("File type acceptable - " + acceptableType);
//  }

//  protected boolean dropComponent(Transferable transferable) throws IOException, UnsupportedFlavorException {
//    Object o = transferable.getTransferData(targetFlavor);
//    if (o instanceof Component) {
//      System.out.println("Dragged component class is "
//          + o.getClass().getName());
//     // pane.add((Component) o);
//     // pane.validate();
//      return true;
//    }
//    return false;
//  }

    // protected boolean acceptableType; // Indicates whether data is acceptable

    //protected DataFlavor targetFlavor; // Flavor to use for transfer
}

